package com.author.surface;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.AttributedString;
import java.util.Stack;

import javax.swing.Action;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTML.Tag;

public class TableButton extends javax.swing.JButton implements ActionListener {
	/** X and Y coordinates of the visible lines */
	private int					x1, x2;
	private int					y1, y2;

	/** Display properties of the button */
	private static final int	TABLE_BUTTON_WIDTH		= 32;
	private static final int	TABLE_BUTTON_HEIGHT		= 32;
	private static final int	TABLE_BUTTON_FONT_SIZE	= 24;

	/** Font used on the table button */
	private Font				tableButtonFont			= new Font(fontName,
																Font.PLAIN,
																TABLE_BUTTON_FONT_SIZE);
	private static final String	fontName				= "Monospaced";

	/** Html text for inserting a table into the text pane */
	public static final String	TABLE_HTML				= "<TABLE BORDER=1><TR><TD></TD></TR></TABLE>";

	public TableButton() {
		setSize(new Dimension(TABLE_BUTTON_WIDTH, TABLE_BUTTON_HEIGHT));
		setPreferredSize(getSize());
		setEnabled(true);

		setBorder(new BevelBorder(BevelBorder.LOWERED));
		setBorderPainted(false);

		// Set visible properties
		setFont(tableButtonFont);
		setToolTipText("Insert Table");
		setFocusable(false);
		setVisible(true);

		// Add action listener
		this.addActionListener(this);
	}

	public void paint(Graphics g) {
		super.paint(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		g2d.setColor(Color.BLACK);
		x1 = 2;
		y1 = 5;
		x2 = 30;
		y2 = 5;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 2;
		y1 = 5;
		x2 = 2;
		y2 = 30;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 16;
		y1 = 5;
		x2 = 16;
		y2 = 30;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 2;
		y1 = 16;
		x2 = 30;
		y2 = 16;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 30;
		y1 = 5;
		x2 = 30;
		y2 = 30;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 2;
		y1 = 30;
		x2 = 30;
		y2 = 30;
		g2d.drawLine(x1, y1, x2, y2);
	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		if (ae == null) return;

		/*
		 * Get information related to editor kit, document model and caret
		 * position
		 */
		HTMLDocument doc = (HTMLDocument) TextPane.getTextPaneDocument();
		HTMLEditorKit kit = (HTMLEditorKit) TextPane.getTextPaneEditorKit();
		int pos = TextPane.getDot();

		/*
		 * Throw an option pane at the user so that the number of rows and the
		 * number of columns for the table can be specified
		 */
		Object[] rowValues = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		Object[] colValues = { 1, 2, 3, 4, 5 };

		final JComboBox rows = new JComboBox(rowValues);
		final JComboBox cols = new JComboBox(colValues);
		final JComponent[] inputs = new JComponent[] {
				new JLabel("Enter ROWS: "), rows, new JLabel("Enter COLS: "),
				cols };

		int rc = JOptionPane.showConfirmDialog(Main.applicationSurface, inputs,
				"TABLE dimensions", JOptionPane.INFORMATION_MESSAGE);
		if ((rc == JOptionPane.CANCEL_OPTION)
				|| (rc == JOptionPane.CLOSED_OPTION)
				|| (rc == JOptionPane.NO_OPTION)) {
			return; /* Nothing to do here, the user has changed his mind */
		}

		/* Get the values selected by the user */
		int numRows = (Integer) rows.getItemAt(rows.getSelectedIndex());
		int numCols = (Integer) cols.getItemAt(cols.getSelectedIndex());

		try {
			String tableHtml = createTableHtml(numRows, numCols);
			kit.insertHTML(doc, pos, tableHtml, 0, 0, null);
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/*
	 * Create the html string for inserting table into the text pane depending
	 * on the number of rows/columns entered by the user
	 */
	private String createTableHtml(int row, int col) {
		final String tableStart = "<TABLE BORDER=1>";
		final String tableEnd = "</TABLE>";

		final String tableRowStart = "<TR>";
		final String tableRowEnd = "</TR>";

		final String tableCellStart = "<TD>";
		final String tableCellEnd = "</TD>";

		String tableHtml = "";
		Stack<String> s = new Stack<String>();

		/* Insert table start tag */
		s.push(tableStart);

		for (int i = 0; i < row; i++) {
			/* Insert Row start tag */
			s.push(tableRowStart);

			for (int j = 0; j < col; j++) {
				/* Insert data cell tag */
				s.push(tableCellStart);

				/* Insert data cell end tag */
				s.push(tableCellEnd);
			}

			/* Insert Row end tag */
			s.push(tableRowEnd);
		}

		/* Insert table end tag */
		s.push(tableEnd);

		/* Reverse the contents of the stack into another stack */
		Stack<String> t = new Stack<String>();
		for (; s.size() != 0;) {
			t.push(s.pop());
		}

		/* Flatten out the contents of t into the html string for the table */
		for (; t.size() != 0;) {
			tableHtml += t.pop();
		}

		return tableHtml;
	}

}
